From 83832f9dc09832ceee0d2bf3ac651361bcc03d27 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 26 Apr 2007 18:33:34 +0100 Subject: [PATCH] hvm: Take care when checking ->is_compat flag now that HVM as well as PV guests can assert it. Signed-off-by: Keir Fraser --- xen/arch/x86/domain.c | 38 ++++++++++++++-------------------- xen/arch/x86/mm/shadow/multi.c | 6 +++--- xen/include/asm-x86/domain.h | 13 ++++++++++++ xen/include/asm-x86/shadow.h | 10 --------- 4 files changed, 31 insertions(+), 36 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 778b08d628..7d7f751cf4 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -237,7 +237,8 @@ static int setup_compat_l4(struct vcpu *v) l4tab[l4_table_offset(LINEAR_PT_VIRT_START)] = l4e_from_page(pg, __PAGE_HYPERVISOR); l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] = - l4e_from_paddr(__pa(v->domain->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); + l4e_from_paddr(__pa(v->domain->arch.mm_perdomain_l3), + __PAGE_HYPERVISOR); v->arch.guest_table = pagetable_from_page(pg); v->arch.guest_table_user = v->arch.guest_table; @@ -259,7 +260,7 @@ static void release_compat_l4(struct vcpu *v) static inline int may_switch_mode(struct domain *d) { - return (d->tot_pages == 0); + return (!is_hvm_domain(d) && (d->tot_pages == 0)); } int switch_native(struct domain *d) @@ -371,15 +372,12 @@ int vcpu_initialise(struct vcpu *v) v->arch.perdomain_ptes = d->arch.mm_perdomain_pt + (v->vcpu_id << GDT_LDT_VCPU_SHIFT); - if ( IS_COMPAT(d) && (rc = setup_compat_l4(v)) != 0 ) - return rc; - - return 0; + return (pv_32on64_vcpu(v) ? setup_compat_l4(v) : 0); } void vcpu_destroy(struct vcpu *v) { - if ( IS_COMPAT(v->domain) ) + if ( pv_32on64_vcpu(v) ) release_compat_l4(v); } @@ -491,7 +489,7 @@ void arch_domain_destroy(struct domain *d) free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3)); #endif - if ( IS_COMPAT(d) ) + if ( pv_32on64_domain(d) ) release_arg_xlat_area(d); free_xenheap_page(d->shared_info); @@ -508,7 +506,7 @@ int arch_set_info_guest( /* The context is a compat-mode one if the target domain is compat-mode; * we expect the tools to DTRT even in compat-mode callers. */ - compat = IS_COMPAT(d); + compat = pv_32on64_domain(d); #ifdef CONFIG_COMPAT #define c(fld) (compat ? (c.cmp->fld) : (c.nat->fld)) @@ -1268,7 +1266,7 @@ unsigned long hypercall_create_continuation( else #endif { - if ( supervisor_mode_kernel || is_hvm_vcpu(current) ) + if ( supervisor_mode_kernel ) regs->eip &= ~31; /* re-execute entire hypercall entry stub */ for ( i = 0; *p != '\0'; i++ ) @@ -1449,14 +1447,11 @@ static void vcpu_destroy_pagetables(struct vcpu *v) struct domain *d = v->domain; unsigned long pfn; -#ifdef CONFIG_COMPAT - if ( IS_COMPAT(d) ) +#ifdef __x86_64__ + if ( pv_32on64_vcpu(v) ) { - if ( is_hvm_vcpu(v) ) - pfn = pagetable_get_pfn(v->arch.guest_table); - else - pfn = l4e_get_pfn(*(l4_pgentry_t *) - __va(pagetable_get_paddr(v->arch.guest_table))); + pfn = l4e_get_pfn(*(l4_pgentry_t *) + __va(pagetable_get_paddr(v->arch.guest_table))); if ( pfn != 0 ) { @@ -1466,12 +1461,9 @@ static void vcpu_destroy_pagetables(struct vcpu *v) put_page_and_type(mfn_to_page(pfn)); } - if ( is_hvm_vcpu(v) ) - v->arch.guest_table = pagetable_null(); - else - l4e_write( - (l4_pgentry_t *) __va(pagetable_get_paddr(v->arch.guest_table)), - l4e_empty()); + l4e_write( + (l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)), + l4e_empty()); v->arch.cr3 = 0; return; diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index 0a49f07add..7002f02567 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -1437,7 +1437,7 @@ static void sh_install_xen_entries_in_l2h(struct vcpu *v, mfn_t sl2hmfn) int i; #else - if ( !pv_32bit_guest(v) ) + if ( !pv_32bit_vcpu(v) ) return; #endif @@ -1685,7 +1685,7 @@ sh_make_monitor_table(struct vcpu *v) l4e = sh_map_domain_page(m4mfn); l4e[0] = l4e_from_pfn(mfn_x(m3mfn), __PAGE_HYPERVISOR); sh_unmap_domain_page(l4e); - if ( pv_32bit_guest(v) ) + if ( pv_32bit_vcpu(v) ) { // Install a monitor l2 table in slot 3 of the l3 table. // This is used for all Xen entries. @@ -2111,7 +2111,7 @@ void sh_destroy_monitor_table(struct vcpu *v, mfn_t mmfn) l4_pgentry_t *l4e = sh_map_domain_page(mmfn); ASSERT(l4e_get_flags(l4e[0]) & _PAGE_PRESENT); m3mfn = _mfn(l4e_get_pfn(l4e[0])); - if ( pv_32bit_guest(v) ) + if ( pv_32bit_vcpu(v) ) { /* Need to destroy the l2 monitor page in slot 3 too */ l3_pgentry_t *l3e = sh_map_domain_page(m3mfn); diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index c9cd69856e..c5f42c2b0e 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -7,6 +7,19 @@ #include #include +#ifdef __x86_64__ +#define pv_32bit_vcpu(v) (!is_hvm_vcpu(v) && IS_COMPAT((v)->domain)) +#define pv_32bit_domain(d) (!is_hvm_domain(d) && IS_COMPAT(d)) +#define pv_32on64_vcpu(v) (pv_32bit_vcpu(v)) +#define pv_32on64_domain(d) (pv_32bit_domain(d)) +#else +#define pv_32bit_vcpu(v) (!is_hvm_vcpu(v)) +#define pv_32bit_domain(d) (!is_hvm_domain(d)) +#define pv_32on64_vcpu(v) (0) +#define pv_32on64_domain(d) (0) +#endif + + struct trap_bounce { uint32_t error_code; uint8_t flags; /* TBF_ */ diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index e08b971e7a..741d6169d8 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -48,16 +48,6 @@ * not yet supported */ #define shadow_mode_trap_reads(_d) ({ (void)(_d); 0; }) -/* - * 32on64 support - */ -#ifdef __x86_64__ -#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v) && IS_COMPAT((_v)->domain)) -#else -#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v)) -#endif - - /***************************************************************************** * Entry points into the shadow code */ -- 2.30.2